package com.moon.game.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.moon.game.cache.LRUCache;
import com.moon.game.clazz.PlayerItemsProto.PlayerItems;
import com.moon.game.clazz.PlayerItemsProto.PlayerItems.PlayerItem;
import com.moon.game.constants.Constants;
import com.moon.game.exception.GException;
import com.moon.game.manager.ItemMG;
import com.moon.game.profile.ProfileService;
import com.moon.game.resource.model.Item;
import com.moon.game.util.GDateUtils;
import com.moon.game.util.IDGenerator;
import com.moon.game.vos.PlayerItemVo;
import com.moon.game.vos.PlayerVo;
import com.moon.game.vos.PlayerVo.UsedItem;

/**
 * @description playeritem服务
 * @author Ranger 作者 E-mail:haozi000005@163.com
 * @version 创建时间：2012-5-1 下午4:46:07
 */
public class PlayerItemService {
	private static final Logger log = Logger.getLogger(PlayerItemService.class);
	private static LRUCache<String, PlayerItems> playerItemCache = new LRUCache<String, PlayerItems>(500);
	/**
	 * 根据id获取人物playeritems
	 * @param playerId
	 * @return
	 */
	public static final List<PlayerItem> getPlayerItems(String playerId) {
		try {
			PlayerItems playerItems = playerItemCache.get(playerId);
			if (playerItems == null) {
				playerItems = ProfileService.getPlayerItemsFromDB(playerId);
			}
			if (playerItems != null) {
				List<PlayerItem> playerItemList = playerItems.getPlayerItemList();
				return playerItemList;
			}
		} catch (GException e1) {
			e1.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 根据playerItemId获得指定道具
	 * 
	 * @param playerId
	 * @param playerItemId
	 * @return 没有返回null
	 */
	public static PlayerItem getPlayerItem(String playerId, long playerItemId) {
		List<PlayerItem> playerItemList = getPlayerItems(playerId);
		if (playerItemList != null) {
			for (PlayerItem playerItem : playerItemList) {
				if (playerItem.getPlayerItemId() == playerItemId) {
					return playerItem;
				}
			}
		}
		return null;
	}
	
	/**
	 * 添加道具(1保存成功，2负重不够，3保存异常)
	 * 
	 * @param player
	 * @param playerItem
	 * @param checkBurden是否检查负重
	 * @return
	 */
	public static int addPlayerItem(String sid, String playerId, PlayerItem playerItem, boolean checkBurden) {
		PlayerItems.Builder newPlayerItems = PlayerItems.newBuilder();
		List<PlayerItem> playerItemList = getPlayerItems(playerId);
		PlayerVo player = PlayerService.doGetPlayer(sid, playerId);
		if (player == null) {
			return Constants.ADD_ITEM_FAIL;
		}
		List<PlayerItem> newPlayerItemList = new ArrayList<PlayerItem>();
		if (playerItemList != null) {
			synchronized (playerItemList) {
				newPlayerItemList.addAll(playerItemList);
			}
		}
		newPlayerItemList.add(playerItem);
		if (checkBurden && !checkBurden(sid, playerId, newPlayerItemList)) {
			log.debug(player.getId() + "there is lack of burden!");
			return Constants.ADD_ITEM_NO_BURDEN;
		}
		newPlayerItems.addAllPlayerItem(newPlayerItemList);
		log.debug("start to add playerItem:" + playerItem.getPlayerItemId());
		syncPlayerItems(player.getId(), newPlayerItems.build());
		log.debug("add playerItem:[" + playerItem.getPlayerItemId() + "]success!");
		return Constants.ADD_ITEM_SUCC;
	}
	
	/**
	 * 删除道具
	 * 
	 * @param playerId
	 * @param playerItemId
	 * @return 7删除装备成功，5没有要删除的道具
	 */
	public static int delPlayerItem(String playerId, long playerItemId) {
		List<PlayerItem> playerItemList = getPlayerItems(playerId);
		PlayerItems.Builder newPlayerItems = PlayerItems.newBuilder();
		boolean hasPlayerItem = false;
		for (PlayerItem playerItem : playerItemList) {
			if (playerItem.getPlayerItemId() == playerItemId) {
				hasPlayerItem = true;
				continue;
			}
			newPlayerItems.addPlayerItem(playerItem);
		}
		if (hasPlayerItem) {
			log.debug("delete playerItem[" + playerItemId + "]and start save list");
			syncPlayerItems(playerId, newPlayerItems.build());
			log.debug("delete playerItem[" + playerItemId + "]and save list success!!");
			return Constants.DEL_ITEM_SUCC;
		}else {
			log.debug("there is no playerItem:" + playerItemId);
			return Constants.DEL_ITEM_LACK;
		}
	}
	
	
	/**
	 * 玩家能否增加addBurden的负重
	 * 
	 * @param player
	 * @param addBurden
	 * @return
	 */
	public static boolean canAddPlayerItem(String sid, String playerId,int addBurden) {
		PlayerVo player = PlayerService.doGetPlayer(sid, playerId);
		if (player == null) {
			return false;
		}
		List<PlayerItem> playerItems = getPlayerItems(playerId);
		if (playerItems == null && player.getBurden() >= addBurden) {
			return true;
		}
		int sum = 0;
		for (PlayerItem playerItem : playerItems) {
			if (playerItem.getIsUse()) {
				continue;
			}
			sum += playerItem.getWeight();
		}
		if (sum + addBurden >= player.getBurden()) {
			return false;
		}else {
			return true;
		}
	}
	
	
	/**
	 * 检测负重（装备才占负重）
	 * 
	 * @param player
	 * @param playerItems
	 * @return
	 */
	private static boolean checkBurden(String sid, String playerId,List<PlayerItem> playerItems) {
		PlayerVo player = PlayerService.doGetPlayer(sid, playerId);
		if (player == null) {
			return false;
		}
		int sum = 0;
		for (PlayerItem playerItem : playerItems) {
			if (playerItem.getIsUse()) {
				continue;
			}
			sum += playerItem.getWeight();
		}
		if (sum >= player.getBurden()) {
			return false;
		}else {
			return true;
		}
	}
	
	/**
	 * 更新装备道具
	 * 
	 * @param player
	 * @param itemId
	 * @param num
	 */
	public static void syncPlayerItems(String playerId, PlayerItems playerItems) {
		try {
			log.debug(playerId + " sync items start...");
			playerItemCache.set(playerId, playerItems);
			ProfileService.savePlayerItems2DB(playerId, playerItems);
			log.debug(playerId + " sync items success!!");
		} catch (GException e) {
			log.error(playerId + " sync items fail!!");
			e.printStackTrace();
		}
	}
	
	/**
	 * 更新装备道具
	 * 
	 * @param player
	 * @param itemId
	 * @param num
	 */
	public static void syncPlayerItem(String playerId, PlayerItem playerItem) {
		List<PlayerItem> playerItemList = getPlayerItems(playerId);
		PlayerItems.Builder newPlayerItems = PlayerItems.newBuilder();
		boolean hasPlayerItem = false;
		if (playerItemList!=null) 
			synchronized (playerItemList) {
				for (PlayerItem item : playerItemList) {
					if (item.getPlayerItemId() == playerItem.getPlayerItemId()) {
						//更新装备
						hasPlayerItem = true;
						newPlayerItems.addPlayerItem(PlayerItem.newBuilder(playerItem));
					}else {
						newPlayerItems.addPlayerItem(item);
					}
				}
			}
		if (hasPlayerItem) {
			log.debug("update playerItem[" + playerItem.getPlayerItemId() + "]and start save list");
			syncPlayerItems(playerId, newPlayerItems.build());
			log.debug("update playerItem[" + playerItem.getPlayerItemId() + "]and save list success!!");
		}/*else {
			log.debug("add playerItem[" + playerItem.getPlayerItemId() + "]and start");
			newPlayerItems.addPlayerItem(playerItem);
			syncPlayerItems(playerId, newPlayerItems.build());
			log.debug("add playerItem[" + playerItem.getPlayerItemId() + "]and success!!");
		}*/
	}
	/**
	 * 创建装备道具
	 * 
	 * @param itemId
	 * @return
	 */
	public static PlayerItem playerItemFactory(int itemId) {
		final Item item = ItemMG.instance.getItem(itemId);
		PlayerItem.Builder newPlayerItem = PlayerItem.newBuilder();
		try {
			if (item == null) {
				log.error("create player item fail,there is no item:" + itemId);
				return null;
			}
			if (item.getType() == 0) {
				log.error("it is not a equip type,item type:" + item.getType() + "; item id:" + itemId);
				return null;
			}
			newPlayerItem.setItemId(itemId);
			newPlayerItem.setName(item.getName());
			newPlayerItem.setLevel(item.getLevel());
			newPlayerItem.setEndure(item.getEndure() * Constants.GAME_MULTIPLE);
			newPlayerItem.setCurEndure(item.getEndure() * Constants.GAME_MULTIPLE);
			newPlayerItem.setPlayerItemId(IDGenerator.generateId(itemId));
			newPlayerItem.setCreateTime(GDateUtils.now());
			newPlayerItem.setUpdateTime(0L);
			newPlayerItem.setAttackColdMax(item.getAttackColdMax());
			newPlayerItem.setAttackColdMin(item.getAttackColdMin());
			newPlayerItem.setAttackHotMax(item.getAttackHotMax());
			newPlayerItem.setAttackHotMin(item.getAttackHotMin());
			newPlayerItem.setDefenseColdMax(item.getDefenseColdMax());
			newPlayerItem.setDefenseColdMin(item.getDefenseColdMin());
			newPlayerItem.setDefenseHotMax(item.getDefenseHotMax());
			newPlayerItem.setDefenseHotMin(item.getDefenseHotMin());
			newPlayerItem.setDescription(item.getDescription());
			newPlayerItem.setNeedCharmValue(item.getNeedCharmValue());
			newPlayerItem.setWeight(item.getWeight());
			return newPlayerItem.build();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("create player item exception,item:" + itemId);
			return null;
		} 
	}
	
	
	/**
	 * 检测道具是否能够被装备false表示不能，true表示能
	 * 
	 * @param player
	 * @param playerItemVo
	 */
	public static boolean checkCanBeEquip(PlayerVo player, PlayerItemVo playerItemVo) {
		if (player.getLevel() < playerItemVo.getLevel()) {
			return false;
		}
		if (player.getCharmValue() < playerItemVo.getNeedCharmValue()) {
			return false;
		}
		if (playerItemVo.isUse()) {
			return false;
		}
		return true;
	}
	
	/**
	 * 检测是否可以被脱掉
	 * 
	 * @param player
	 * @param playerItemId
	 * @return 0卸载正常，-1该道具已经不在身上了
	 */
	public static int takeOffTheEquip(PlayerVo player, long playerItemId) {
		List<UsedItem> items = player.getUsedItem();
		List<UsedItem> newItems = new ArrayList<PlayerVo.UsedItem>();
		boolean canbeTakeOff = false;
		for (UsedItem item:items) {
			if(item.getId() == playerItemId){
				canbeTakeOff = true;
				continue;
			}else {
				newItems.add(item);
			}
		}
		if (player.getUsedItem() != null) {
			player.getUsedItem().clear();
		}
		player.setUsedItem(newItems);
		if (canbeTakeOff) {
			return 0;
		}else {
			return -1;
		}
		
	}
	
	
	/**
	 * 装备道具内存到DB
	 * 
	 * @param vo
	 * @return
	 */
	public static PlayerItem transVo2Db(PlayerItemVo vo) {
		PlayerItem.Builder playerItem = PlayerItem.newBuilder();
		playerItem.setItemId(vo.getItemId());
		playerItem.setPlayerItemId(vo.getPlayerItemId());
		playerItem.setCreateTime(vo.getCreateTime());
		playerItem.setBroken(vo.isBroken());
		playerItem.setCurEndure(vo.getCurEndure());
		playerItem.setEndure(vo.getEndure());
		playerItem.setIsUse(vo.isUse());
		playerItem.setLevel(vo.getLevel());
		playerItem.setName(vo.getName());
		playerItem.setNeedCharmValue(vo.getNeedCharmValue());
		if (vo.getGem() != null) {
			playerItem.addAllGem(vo.getGem());
		}
		if (vo.getPropertyIds() != null) {
			playerItem.addAllPropertyIds(vo.getPropertyIds());
		}
		playerItem.setImproveLevel(vo.getImproveLevel());
		playerItem.setAttackColdMax(vo.getAttackColdMax());
		playerItem.setAttackColdMin(vo.getAttackColdMin());
		playerItem.setAttackHotMax(vo.getAttackHotMax());
		playerItem.setAttackHotMin(vo.getAttackHotMin());
		playerItem.setDefenseColdMax(vo.getDefenseColdMax());
		playerItem.setDefenseColdMin(vo.getDefenseColdMin());
		playerItem.setDefenseHotMax(vo.getDefenseHotMax());
		playerItem.setDefenseHotMin(vo.getDefenseHotMin());
		playerItem.setDescription(vo.getDescription());
		playerItem.setWeight(vo.getWeight());
		return playerItem.build();
	}
	
	/**
	 * 装备道具DB到内存
	 * 
	 * @param playerItem
	 * @return
	 */
	public static PlayerItemVo transDb2Vo(PlayerItem playerItem) {
		PlayerItemVo vo = new PlayerItemVo();
		vo.setItemId(playerItem.getItemId());
		vo.setPlayerItemId(playerItem.getPlayerItemId());
		vo.setCreateTime(playerItem.getCreateTime());
		vo.setBroken(playerItem.getBroken());
		vo.setCurEndure(playerItem.getCurEndure());
		vo.setEndure(playerItem.getEndure());
		vo.setUse(playerItem.getIsUse());
		vo.setLevel(playerItem.getLevel());
		vo.setName(playerItem.getName());
		vo.setNeedCharmValue(playerItem.getNeedCharmValue());
		if (vo.getGem() != null) {
			vo.setGem(playerItem.getGemList());
		}
		if (vo.getPropertyIds() != null) {
			vo.setPropertyIds(playerItem.getPropertyIdsList());
		}
		vo.setImproveLevel(playerItem.getImproveLevel());
		vo.setAttackColdMax(playerItem.getAttackColdMax());
		vo.setAttackColdMin(playerItem.getAttackColdMin());
		vo.setAttackHotMax(playerItem.getAttackHotMax());
		vo.setAttackHotMin(playerItem.getAttackHotMin());
		vo.setDefenseColdMax(playerItem.getDefenseColdMax());
		vo.setDefenseColdMin(playerItem.getDefenseColdMin());
		vo.setDefenseHotMax(playerItem.getDefenseHotMax());
		vo.setDefenseHotMin(playerItem.getDefenseHotMin());
		vo.setDescription(playerItem.getDescription());
		vo.setWeight(playerItem.getWeight());
		return vo;
	}
}
